package com.audio;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 成功版
 */
public class JavaCVAudioSplitter {

    /**
     * 将长音频每 10 秒切割，并存入列表
     *
     * @param inputFile 输入音频文件路径
     * @param outputDir 输出音频段存储目录
     * @param segmentDurationMs 每段音频的时长（毫秒）
     * @return 包含所有音频段文件的列表
     * @throws Exception 如果处理失败
     */
    public static List<File> splitAudioToSegments(String inputFile, String outputDir, int segmentDurationMs) throws Exception {
        List<File> audioSegments = new ArrayList<>(); // 用于存储每段音频文件的列表

        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);
        grabber.start(); // 启动音频抓取器

        long totalDurationMs = grabber.getLengthInTime() / 1000; // 获取音频总时长（毫秒）
        int segmentIndex = 0; // 每段音频的索引

        // 按时间段切割音频
        for (long startMs = 0; startMs < totalDurationMs; startMs += segmentDurationMs) {
            long endMs = Math.min(startMs + segmentDurationMs, totalDurationMs); // 计算当前段的结束时间

            // 输出文件路径
            File outputFile = new File(outputDir, String.format("segment_%03d.mp3", segmentIndex++));
            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, grabber.getAudioChannels());
            recorder.setSampleRate(grabber.getSampleRate());
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_MP3);
            recorder.setFormat("mp3");
            recorder.start();

            Frame frame;
            while ((frame = grabber.grabFrame()) != null) {
                if (frame.samples == null) {
                    continue; // 如果帧中没有音频样本，跳过
                }
                long timestampMs = grabber.getTimestamp() / 1000; // 当前帧的时间戳（毫秒）
                if (timestampMs >= startMs && timestampMs < endMs) {
                    recorder.recordSamples(frame.samples); // 记录当前帧的音频样本
                }
                if (timestampMs >= endMs) {
                    break; // 如果超过当前段的结束时间，退出循环
                }
            }

            recorder.stop(); // 停止录制
            recorder.release(); // 释放资源

            audioSegments.add(outputFile); // 将生成的文件添加到列表
        }

        grabber.stop(); // 停止抓取器
        grabber.release(); // 释放资源

        return audioSegments; // 返回所有音频段文件
    }

    public static void main(String[] args) {
        try {
            // 输入音频文件路径
            String inputFile = "D:\\Code idea\\AudioDemo\\src\\main\\resources\\static\\in\\test1.mp3";
            // 输出目录路径
            String outputDir = "D:\\Code idea\\AudioDemo\\src\\main\\resources\\static\\out";

            // 创建输出目录（如果不存在）
            File outputDirectory = new File(outputDir);
            if (!outputDirectory.exists()) {
                outputDirectory.mkdirs();
            }

            // 调用方法切割音频，每段 10 秒（10,000 毫秒）
            List<File> audioSegments = splitAudioToSegments(inputFile, outputDir, 10000);

            // 打印每段音频文件路径
            System.out.println("音频分割完成，生成的文件如下：");
            for (File segment : audioSegments) {
                System.out.println(segment.getAbsolutePath());
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("音频分割失败: " + e.getMessage());
        }
    }
}
